package com.campsys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.campsys.entity.Course;
import com.campsys.entity.CourseStudent;
import com.campsys.entity.TeachingUnit;
import com.campsys.entity.LearningRecord;
import com.campsys.entity.RollCall;
import com.campsys.entity.RollCallRecord;
import com.campsys.mapper.*;
import com.campsys.service.StudentService;
import com.campsys.service.dto.StudentCourseDTO;
import com.campsys.service.dto.StudentLearningDTO;
import com.campsys.service.dto.StudentRollCallDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Service
@Slf4j
public class StudentServiceImpl implements StudentService {
    
    @Autowired
    private CourseMapper courseMapper;
    
    @Autowired
    private CourseStudentMapper courseStudentMapper;
    
    @Autowired
    private TeachingUnitMapper unitMapper;
    
    @Autowired
    private LearningRecordMapper learningRecordMapper;
    
    @Autowired
    private RollCallMapper rollCallMapper;
    
    @Autowired
    private RollCallRecordMapper rollCallRecordMapper;
    
    @Override
    public IPage<StudentCourseDTO> getMyCourses(Page<StudentCourseDTO> page, Long studentId) {
        return courseMapper.selectStudentCourses(page, studentId);
    }
    
    @Override
    public IPage<TeachingUnit> getCourseUnits(Page<TeachingUnit> page, Long courseId, Long studentId) {
        // 验证学生是否已加入课程
        validateCourseJoined(courseId, studentId);
        
        LambdaQueryWrapper<TeachingUnit> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TeachingUnit::getCourseId, courseId)
              .eq(TeachingUnit::getStatus, 1)  // 只查询已发布的单元
              .orderByAsc(TeachingUnit::getSort);
        
        return unitMapper.selectPage(page, wrapper);
    }
    
    @Override
    public StudentLearningDTO getUnitLearning(Long unitId, Long studentId) {
        // 获取教学单元信息
        TeachingUnit unit = unitMapper.selectById(unitId);
        if (unit == null || unit.getStatus() != 1) {
            throw new IllegalArgumentException("教学单元不存在或未发布");
        }
        
        // 验证学生是否已加入课程
        validateCourseJoined(unit.getCourseId(), studentId);
        
        // 获取或创建学习记录
        LearningRecord record = getOrCreateLearningRecord(unitId, studentId);
        
        StudentLearningDTO dto = new StudentLearningDTO();
        dto.setUnitId(unitId);
        dto.setUnitTitle(unit.getTitle());
        dto.setDocumentUrl(unit.getDocumentUrl());
        dto.setVideoUrl(unit.getVideoUrl());
        dto.setPoints(unit.getPoints());
        dto.setStatus(record.getStatus());
        dto.setStartTime(record.getStartTime());
        dto.setCompleteTime(record.getCompleteTime());
        
        return dto;
    }
    
    @Override
    @Transactional
    public void startLearning(Long unitId, Long studentId) {
        // 获取教学单元信息
        TeachingUnit unit = unitMapper.selectById(unitId);
        if (unit == null || unit.getStatus() != 1) {
            throw new IllegalArgumentException("教学单元不存在或未发布");
        }
        
        // 验证学生是否已加入课程
        validateCourseJoined(unit.getCourseId(), studentId);
        
        // 创建学习记录
        LearningRecord record = new LearningRecord();
        record.setUnitId(unitId);
        record.setStudentId(studentId);
        record.setStatus(0);  // 进行中
        record.setStartTime(LocalDateTime.now());
        
        learningRecordMapper.insert(record);
    }
    
    @Override
    @Transactional
    public void completeLearning(Long unitId, Long studentId) {
        // 获取教学单元信息
        TeachingUnit unit = unitMapper.selectById(unitId);
        if (unit == null || unit.getStatus() != 1) {
            throw new IllegalArgumentException("教学单元不存在或未发布");
        }
        
        // 验证学生是否已加入课程
        validateCourseJoined(unit.getCourseId(), studentId);
        
        // 获取学习记录
        LearningRecord record = getLearningRecord(unitId, studentId);
        if (record == null) {
            throw new IllegalArgumentException("请先开始学习");
        }
        if (record.getStatus() == 1) {
            throw new IllegalArgumentException("该单元已完成学习");
        }
        
        // 更新学习记录
        record.setStatus(1);  // 已完成
        record.setPoints(unit.getPoints());
        record.setCompleteTime(LocalDateTime.now());
        
        learningRecordMapper.updateById(record);
    }
    
    @Override
    public String getDocumentUrl(Long unitId, Long studentId) {
        // 获取教学单元信息
        TeachingUnit unit = unitMapper.selectById(unitId);
        if (unit == null || unit.getStatus() != 1) {
            throw new IllegalArgumentException("教学单元不存在或未发布");
        }
        
        // 验证学生是否已加入课程
        validateCourseJoined(unit.getCourseId(), studentId);
        
        return unit.getDocumentUrl();
    }
    
    @Override
    public String getVideoUrl(Long unitId, Long studentId) {
        // 获取教学单元信息
        TeachingUnit unit = unitMapper.selectById(unitId);
        if (unit == null || unit.getStatus() != 1) {
            throw new IllegalArgumentException("教学单元不存在或未发布");
        }
        
        // 验证学生是否已加入课程
        validateCourseJoined(unit.getCourseId(), studentId);
        
        return unit.getVideoUrl();
    }
    
    @Override
    public IPage<StudentRollCallDTO> getRollCallList(Page<StudentRollCallDTO> page, Long courseId, Long studentId) {
        // 验证学生是否已加入课程
        validateCourseJoined(courseId, studentId);
        
        return rollCallMapper.selectStudentRollCalls(page, courseId, studentId);
    }
    
    @Override
    @Transactional
    public void signRollCall(Long rollCallId, Long studentId) {
        // 获取点名信息
        RollCall rollCall = rollCallMapper.selectById(rollCallId);
        if (rollCall == null) {
            throw new IllegalArgumentException("点名不存在");
        }
        
        // 验证学生是否已加入课程
        validateCourseJoined(rollCall.getCourseId(), studentId);
        
        // 验证点名状态
        LocalDateTime now = LocalDateTime.now();
        if (now.isBefore(rollCall.getStartTime())) {
            throw new IllegalArgumentException("点名尚未开始");
        }
        if (now.isAfter(rollCall.getEndTime())) {
            throw new IllegalArgumentException("点名已结束");
        }
        
        // 检查是否已经点名
        LambdaQueryWrapper<RollCallRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RollCallRecord::getRollCallId, rollCallId)
              .eq(RollCallRecord::getStudentId, studentId);
        if (rollCallRecordMapper.selectCount(wrapper) > 0) {
            throw new IllegalArgumentException("您已完成点名");
        }
        
        // 创建点名记录
        RollCallRecord record = new RollCallRecord();
        record.setRollCallId(rollCallId);
        record.setStudentId(studentId);
        record.setStatus(1);  // 1-出勤
        record.setSignTime(now);
        
        rollCallRecordMapper.insert(record);
    }
    
    private void validateCourseJoined(Long courseId, Long studentId) {
        LambdaQueryWrapper<CourseStudent> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CourseStudent::getCourseId, courseId)
              .eq(CourseStudent::getStudentId, studentId)
              .eq(CourseStudent::getStatus, 1);  // 1-正常状态
        
        if (courseStudentMapper.selectCount(wrapper) == 0) {
            throw new IllegalArgumentException("您尚未加入该课程");
        }
    }
    
    private LearningRecord getOrCreateLearningRecord(Long unitId, Long studentId) {
        // 查找现有记录
        LearningRecord record = getLearningRecord(unitId, studentId);
        if (record == null) {
            // 创建新记录
            record = new LearningRecord();
            record.setUnitId(unitId);
            record.setStudentId(studentId);
            record.setStatus(0);  // 进行中
            record.setStartTime(LocalDateTime.now());
            learningRecordMapper.insert(record);
        }
        return record;
    }
    
    private LearningRecord getLearningRecord(Long unitId, Long studentId) {
        LambdaQueryWrapper<LearningRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LearningRecord::getUnitId, unitId)
              .eq(LearningRecord::getStudentId, studentId);
        return learningRecordMapper.selectOne(wrapper);
    }
} 